home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / AT.C < prev    next >
C/C++ Source or Header  |  1990-06-08  |  4KB  |  174 lines

  1. /* run a command at certain time-of-day */
  2.  
  3. #include <time.h>
  4. #include "global.h"
  5. #include "timer.h"
  6. #include "cmdparse.h"
  7.  
  8. #if (defined(MSDOS) && !(defined(MSC)) && !(defined(__TURBOC__)))
  9. # define TIMEZONE    0L        /* Aztec doesn't define timezone */
  10. #endif
  11.  
  12. #ifdef UNIX
  13. # define TIMEZONE    (daylight? altzone : timezone) /* XENIX has "altzone" */
  14. #endif
  15.  
  16. #ifdef MWC
  17. # define TIMEZONE    timezone    /* MWC does not know "daylight" */
  18. #endif
  19.  
  20. #ifndef TIMEZONE
  21. # define TIMEZONE    (daylight? timezone - 3600L : timezone)
  22. #endif
  23.  
  24. struct at
  25. {
  26.     struct at *next,*prev;        /* doubly-linked list */
  27.     time_t when;            /* time-of-day */
  28.     int argc;                /* description of command */
  29.     char *argv[NARG];            /* pointers to copied args */
  30. };
  31. #define NULLAT    ((struct at *) 0)
  32.  
  33. struct at *at_head = NULLAT;        /* list of scheduled commands */
  34. time_t lasttime = 0;            /* last time we executed one */
  35.  
  36. struct timer at_timer;            /* 1-minute timer to execute cmds */
  37.  
  38. static void at_tick();
  39.  
  40. extern struct cmds cmds[];        /* commands */
  41. extern char nospace[];
  42.  
  43. int
  44. doat (argc,argv)
  45.     int argc;
  46.     char *argv[];
  47.  
  48. {
  49.     register struct at *at,*new;
  50.     char *p;
  51.     time_t when;
  52.     int i;
  53.  
  54.     if (argc < 2) {
  55.     printf("Time   Command\n");
  56.     for (at = at_head; at != NULLAT; at = at->next){
  57.         i = (int) (at->when / 60L);
  58.         printf("%2d:%02d ",i / 60,i % 60);
  59.         for (i = 0; i < at->argc; i++)
  60.         printf(" %s",at->argv[i]);
  61.         printf("\n");
  62.     }
  63.     return 0;
  64.     }
  65.     if ((p = index(argv[1],':')) == NULLCHAR){
  66.     printf("Usage: at hh:mm [command]\n");
  67.     return 1;
  68.     }
  69.     if ((when = 3600L * atoi(argv[1]) + 60 * atoi(p + 1)) >= 86400L){
  70.     printf("at: illegal time\n");
  71.     return 1;
  72.     }
  73.     for (at = at_head; at != NULLAT; at = at->next)
  74.     if (at->when == when){
  75.         for (i = 0; i < at->argc; i++)
  76.         free(at->argv[i]);
  77.  
  78.         if (at->next != NULLAT)
  79.         at->next->prev = at->prev;
  80.  
  81.         if (at->prev != NULLAT)
  82.         at->prev->next = at->next;
  83.         else
  84.         at_head = at->next;
  85.  
  86.         free(at);
  87.         break;
  88.     }
  89.     if (argc > 2){
  90.     /* create new "at" control block */
  91.     if ((new = (struct at *) calloc(1,sizeof(struct at))) == NULLAT){
  92.         printf(nospace);
  93.         return 1;
  94.     }
  95.     new->when = when;
  96.     new->argc = argc - 2;
  97.     /* copy command and args to allocated space and link to "at" block */
  98.     for (i = 0; i < new->argc; i++){
  99.         if ((new->argv[i] = malloc(strlen(argv[i + 2]) + 1)) == NULLCHAR){
  100.         while (--i >= 0)
  101.             free(new->argv[i]);
  102.         free(new);
  103.         printf(nospace);
  104.         return 1;
  105.         }
  106.         strcpy(new->argv[i],argv[i + 2]);
  107.     }
  108.     /* find proper position in the list (sorted on time-of-day) */
  109.     for (at = at_head; at != NULLAT; at = at->next)
  110.         if (at->when > when)
  111.         break;
  112.     if (at == NULLAT){
  113.         if (at_head == NULLAT)
  114.         at_head = new;
  115.         else {
  116.         for (at = at_head; at->next != NULLAT; at = at->next)
  117.             ;                /* find end of list */
  118.         at->next = new;
  119.         new->prev = at;
  120.         }
  121.     } else {                /* insert before this one */
  122.         if ((new->prev = at->prev) != NULLAT)
  123.         new->prev->next = new;
  124.         else
  125.         at_head = new;
  126.         at->prev = new;
  127.         new->next = at;
  128.     }
  129.     }
  130.  
  131.     stop_timer(&at_timer);
  132.     if (at_head != NULLAT){            /* anything to run? */
  133.     if (at_timer.start == 0){        /* first time? */
  134.         at_timer.start = SEC2TICK(60);    /* tick each minute */
  135.         at_timer.func = at_tick;
  136.         lasttime = (time(NULL) - TIMEZONE) % 86400L; /* init last-time-done */
  137.     }
  138.     start_timer(&at_timer);
  139.     at_timer.count = SEC2TICK(60 - (time(NULL) % 60)); /* sync with minute */
  140.     }
  141.     return 0;
  142. }
  143.  
  144. /* called once a minute to check for commands to run */
  145.  
  146. static void
  147. at_tick ()
  148.  
  149. {
  150.     register struct at *at;
  151.     time_t now;
  152.     char *argv[NARG];
  153.  
  154.     at = at_head;
  155.     now = (time(NULL) - TIMEZONE) % 86400L;    /* get time of day */
  156.  
  157.     /* skip all commands that already have been processed */
  158.     if (now > lasttime)
  159.     while (at != NULLAT && at->when <= lasttime)
  160.         at = at->next;
  161.  
  162.     while (at != NULLAT){
  163.     if (at->when <= now){            /* time to run it? */
  164.         memcpy(argv,at->argv,NARG * sizeof(char *)); /* copy arg vector */
  165.         docmd(cmds,at->argc,argv);        /* and go! */
  166.     }
  167.  
  168.     at = at->next;
  169.     }
  170.  
  171.     lasttime = now;                /* remember last time */
  172.     start_timer(&at_timer);            /* look again in a minute */
  173. }
  174.